/*
 *
 *  *
 *  *  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
 *  *  SPDX-License-Identifier: Apache-2.0
 *  *
 *
 */

import React, { useCallback, useRef } from 'react';
import { Button, Form, Icon, Input, Select, Text } from 'tea-component';
// import { useForm, useField } from 'react-final-form-hooks';
import { Controller, useForm, useWatch } from 'react-hook-form';
import { Subscribe } from '@src/models';
import validate from '@src/utils/validate';
import FileUpload from '../FileUpload';
import style from './index.module.scss';
import { AuthTypeOptions, HashTypeOptions } from '@src/utils/enums';
import { getStatus } from '@src/utils/form';
import SubscribeNodeForm from './node';

export default function SubscribeForm({
  onSubmit,
  onCancel,
  initialData,
  submitText,
  cancelText,
}: {
  onSubmit: (value: Subscribe) => void;
  onCancel: () => void;
  initialData?: {
    ChainId: string;
    AuthType: string;
  };
  submitText?: string;
  cancelText?: string;
}) {
  const refs = useRef<any[]>([]);
  const {
    control,
    getValues,
    setValue,
    handleSubmit,
    formState: { isValidating, isSubmitted }
  } = useForm({
    mode: 'onChange',
    defaultValues: {
      ChainId: initialData?.ChainId || '',
      AuthType: initialData?.AuthType || 'permissionedwithcert',
      OrgId: '',
      UserCert: '',
      NodeList: [{
        Addr: '',
        Tls: true,
        OrgCA: '',
        TLSHostName: 'chainmaker.org',
      }],
      UserKey: '',
      HashType: '',
    }
  });
  const authType = useWatch({ control, name: 'AuthType' });
  const nodeList = useWatch({ control, name: 'NodeList' });
  const deleteNode = useCallback((index) => {
    nodeList.splice(index, 1);
    setValue('NodeList', nodeList);
  }, [nodeList]);
  const updateNode = useCallback((node, index) => {
    nodeList[index] = node;
    setValue('NodeList', nodeList);
  }, [nodeList]);
  const addNode = useCallback(() => {
    nodeList.push({
      Addr: '',
      Tls: true,
      OrgCA: '',
      TLSHostName: 'chainmaker.org',
    });
    setValue('NodeList', nodeList);
  }, [nodeList]);
  const sumbitForm = useCallback(async () => {
    for (let i = 0; i < refs.current.length; i++) {
      if (refs.current[i]?.handle) {
        const pass = await refs.current[i].handle();
        if (!pass) {
          return;
        }
      }
    }
    const { ChainId, AuthType, OrgId, UserCert, UserKey, HashType, NodeList } = getValues();
    if (AuthType === 'permissionedwithcert') {
      onSubmit({
        ChainId,
        AuthType,
        NodeList,
        OrgId,
        UserCert,
        UserKey,
      });
    } else {
      onSubmit({
        ChainId,
        AuthType,
        NodeList: NodeList.map((node) => ({
          ...node,
          Tls: false,
        })),
        UserKey,
        HashType: Number(HashType),
      });
    }
  }, [onSubmit, getValues]);

  return (
    <div className={style.content}>
      <Form
        layout="fixed"
        fixedLabelWidth="140px"
      >
        <Controller
          control={control}
          rules={{
            required: '请输入区块链Id',
            validate: validate.chainId
          }}
          name="ChainId"
          render={({ field, fieldState }) => (
            <Form.Item required
              label="区块链ID"
              status={getStatus({
                fieldState,
                isValidating,
                isSubmitted
              })}
              message={fieldState.error?.message}>
              {!initialData?.ChainId && <Input placeholder="请输入区块链Id" {...field} />}
              {initialData?.ChainId && <Text theme="label">{initialData.ChainId}</Text>}
            </Form.Item>)}
        />
        <Controller
          control={control}
          rules={{
            required: '请选择账户模式'
          }}
          name="AuthType"
          render={({ field, fieldState }) => (
            <Form.Item required label="帐号模式"
              status={getStatus({
                fieldState,
                isValidating,
                isSubmitted
              })}
              message={fieldState.error?.message}>
              {!initialData?.AuthType && (
                <Select
                  appearance="button"
                  style={{
                    width: 400,
                    height: 40,
                    lineHeight: 40,
                    fontSize: 14,
                  }}
                  matchButtonWidth={true}
                  options={AuthTypeOptions}
                  placeholder="请选择账户模式"
                  {...field}
                />
              )}
              {initialData?.AuthType && <Text theme="label">{initialData.AuthType}</Text>}
            </Form.Item>)}
        />
        {authType !== 'public' || (
          <Controller
            name="HashType"
            control={control}
            rules={{
              required: '请选择密码算法'
            }}
            render={({ field, fieldState }) => (
              <Form.Item
                required
                label="密码算法"
                status={getStatus({
                  fieldState,
                  isValidating,
                  isSubmitted
                })}
                message={fieldState.error?.message}>
                <Select
                  appearance="button"
                  style={{
                    width: 400,
                    height: 40,
                    lineHeight: 40,
                    fontSize: 14,
                  }}
                  matchButtonWidth={true}
                  options={HashTypeOptions}
                  placeholder="请选择密码算法"
                  {...field}
                />
              </Form.Item>)}
          />
        )}
        {authType !== 'permissionedwithcert' || (
          <>
            <Controller
              control={control}
              rules={{
                required: '请输入组织Id'
              }}
              name="OrgId"
              render={({ field, fieldState }) => (
                <Form.Item required label="用户所在的组织Id  "
                  status={getStatus({
                    fieldState,
                    isValidating,
                    isSubmitted
                  })}
                  message={fieldState.error?.message}>
                  <Input
                    placeholder="请输入组织Id"
                    {...field}/>
                </Form.Item>)}
            />
            <Controller
              control={control}
              rules={{
                required: '请上传用户签名证书'
              }}
              name="UserCert"
              render={({ field, fieldState }) => (
                <Form.Item
                  required
                  label="用户签名证书"
                  status={getStatus({
                    fieldState,
                    isValidating,
                    isSubmitted
                  })}
                  message={fieldState.error?.message}
                >
                  <FileUpload
                    accept=".crt"
                    {...field}
                    fileName="用户签名证书"
                  />
                </Form.Item>)}
            />
          </>
        )}
        <Controller
          control={control}
          rules={{
            required: '请上传用户签名私钥'
          }}
          name="UserKey"
          render={({ field, fieldState }) => (
            <Form.Item
              required
              label="用户签名私钥"
              status={getStatus({
                fieldState,
                isValidating,
                isSubmitted
              })}
              message={fieldState.error?.message}>
              <FileUpload
                fileName="用户签名私钥"
                accept=".key"
                {...field} />
            </Form.Item>)}
        />
      </Form>
      {
        nodeList.map((node, index) => (
          <div
            key={index} className={style.node_item}>
            {index === 0 || <div className={style.node_item_close}>
              <Icon onClick={() => deleteNode(index)} type="close" />
            </div>}
            <SubscribeNodeForm
              ref={ref => {
                refs.current[index] = ref;
              }}
              isStandby={index !== 0}
              authType={authType}
              nodeinfo={node}
              onChange={(value) => updateNode(value, index)}/>
          </div>
        ))
      }
      {nodeList.length >= 5 || <div className={style.add_node}>
        <Button type='primary' onClick={addNode}>增加备用节点</Button>
      </div>}
      {authType === 'permissionedwithcert' && (
        <div className={style.rule}>
          <div className={style.rule_i}>
          1. 请确保本处上传的组织证书、用户证书、用户私钥、节点信息都属于要订阅链，所上传的用户证书需要属于所填写的组织id名下，节点地址需要是所上传的组织证书名下的。
          </div>
          <div className={style.rule_i}>2. 推荐填写所要订阅的链的共识节点的IP和RPC端口，并确保网络通畅。</div>
          <div className={style.rule_i}>3.备用节点节点用于如果主订阅节点故障了，将切换至备用节点获取链上数据，非必填项，可根据实际情况选配。</div>
          <div className={style.rule_i}>4. 如果您的节点同时参与了多条链，请根据区块链ID区分你要订阅具体哪条链。</div>
          {/* <div className={style.rule_i_d}>- IP和RPC端口是否开放、是否正确。</div>
          <div className={style.rule_i_d}>- TLS是否选择正确，TLSHostName是否正确。</div>
          <div className={style.rule_i_d}>- 组织证书和所选用户证书是否为同一套。</div>
          <div className={style.rule_i_d}>- 用户证书尽量保证使用SIGN证书。</div>
          <div className={style.rule_i_d}>- 区块链ID是否正确。</div> */}
        </div>
      )}
      {authType === 'public' && (
        <div className={style.rule}>
          <div className={style.rule_i}>1. 推荐填写所要订阅的链的共识节点的IP和RPC端口，并确保网络通畅。</div>
          <div className={style.rule_i}>2.备用节点节点用于如果主订阅节点故障了，将切换至备用节点获取链上数据，非必填项，可根据实际情况选配。</div>
          <div className={style.rule_i}>3. 如果您的节点同时参与了多条链，请根据区块链ID区分你要订阅具体哪条链。</div>
        </div>
      )}
      {(cancelText || submitText) && (
        <Form.Action>
          {cancelText && (
            <Button
              style={{ height: 40, width: 120, fontSize: 16, marginRight: 80 }}
              type="weak"
              onClick={onCancel}
            >
              {cancelText}
            </Button>
          )}
          {submitText && (
            <Button
              style={{ height: 40, width: 120, fontSize: 16 }}
              type="primary"
              onClick = {handleSubmit(sumbitForm)}
            >
              {submitText}
            </Button>
          )}
        </Form.Action>
      )}
    </div>
  );
}
